import logging
import logging
import uuid
from flask_socketio import SocketIO, join_room, leave_room, emit
from flask import request
from flask_jwt_extended import jwt_required, get_jwt_identity
from extensions import socketio
from models.user_models import User
from models.message_models import Message
from extensions import db
import jwt

logger = logging.getLogger(__name__)

def init_socket_handlers():
    """初始化WebSocket事件处理器"""
    
    @socketio.on('connect')
    def handle_connect():
        """处理客户端连接"""
        try:
            # 从认证头或auth对象获取token
            token = None
            if hasattr(request, 'auth') and request.auth:
                token = request.auth.get('token')
            if not token:
                token = request.args.get('token')
            if not token:
                auth_header = request.headers.get('Authorization', '')
                if auth_header.startswith('Bearer '):
                    token = auth_header[7:]  # 移除'Bearer '
            
            if not token:
                logger.warning("WebSocket连接缺少token")
                return False
            
            # 使用JWT验证token
            try:
                payload = jwt.decode(token, 'dev-jwt-secret-1234567890abcdef', algorithms=['HS256'])
                user_id = payload.get('user_id')
                if not user_id:
                    logger.warning("WebSocket token无效: 缺少user_id")
                    return False
                    
                user_uuid = uuid.UUID(user_id)
                user = User.query.get(user_uuid)
                if not user:
                    logger.warning(f"WebSocket用户不存在: {user_id}")
                    return False
                    
                # 加入用户房间
                join_room(str(user_uuid))
                
                # 更新用户在线状态
                user.online = True
                db.session.commit()
                
                # 通知其他用户该用户上线
                emit('user_status', {
                    'user_id': str(user_uuid),
                    'username': user.username,
                    'status': 'online'
                }, broadcast=True, include_self=False)
                
                logger.info(f"用户 {user.username} WebSocket连接成功")
                return True
                
            except jwt.InvalidTokenError as e:
                logger.warning(f"WebSocket token验证失败: {str(e)}")
                return False
                
        except Exception as e:
            logger.error(f"WebSocket连接错误: {str(e)}")
            return False
    
    @socketio.on('disconnect')
    def handle_disconnect():
        """处理客户端断开连接"""
        try:
            # 获取用户ID（从连接时存储的信息）
            logger.info("客户端WebSocket断开连接")
            
            # 实际应该根据socket ID查找对应的用户
            # 这里简化处理
            
        except Exception as e:
            logger.error(f"WebSocket断开错误: {str(e)}")
    
    @socketio.on('private_message')
    def handle_private_message(data):
        """处理私聊消息"""
        try:
            # 验证token
            token = None
            if hasattr(request, 'auth') and request.auth:
                token = request.auth.get('token')
            if not token:
                token = request.args.get('token')
            if not token:
                auth_header = request.headers.get('Authorization', '')
                if auth_header.startswith('Bearer '):
                    token = auth_header[7:]
            
            if not token:
                emit('error', {'message': '未授权'})
                return
            
            try:
                payload = jwt.decode(token, 'dev-jwt-secret-1234567890abcdef', algorithms=['HS256'])
                sender_id = payload.get('user_id')
                if not sender_id:
                    emit('error', {'message': 'token无效'})
                    return
            except jwt.InvalidTokenError:
                emit('error', {'message': 'token无效'})
                return
            
            receiver_id = data.get('receiver_id')
            content = data.get('content')
            
            if not receiver_id or not content:
                emit('error', {'message': '参数不完整'})
                return
            
            # 验证接收者是否存在
            try:
                receiver_uuid = uuid.UUID(receiver_id)
                receiver = User.query.get(receiver_uuid)
                if not receiver:
                    emit('error', {'message': '接收者不存在'})
                    return
            except ValueError:
                emit('error', {'message': '接收者ID格式错误'})
                return
            
            # 创建消息记录
            message = Message(
                sender_id=uuid.UUID(sender_id),
                receiver_id=receiver_uuid,
                content=content,
                encrypted_content=content,  # 简化处理
                message_key='test_key',
                nonce='test_nonce',
                tag='test_tag',
                is_read=False
            )
            
            db.session.add(message)
            db.session.commit()
            
            # 发送消息给接收者
            socket_message = {
                'id': str(message.id),
                'sender_id': str(message.sender_id),
                'receiver_id': str(message.receiver_id),
                'content': message.content,
                'encrypted_content': message.encrypted_content,
                'timestamp': message.timestamp.isoformat(),
                'is_read': message.is_read
            }
            
            # 发送到接收者的房间
            emit('new_message', socket_message, room=str(receiver_uuid))
            
            # 确认消息已发送
            emit('message_sent', {
                'message_id': str(message.id),
                'timestamp': message.timestamp.isoformat()
            })
            
            logger.info(f"消息从 {sender_id} 发送到 {receiver_id}")
            
        except Exception as e:
            logger.error(f"WebSocket消息处理错误: {str(e)}")
            emit('error', {'message': '消息发送失败'})
    
    @socketio.on('join_room')
    def handle_join_room(data):
        """处理加入房间"""
        try:
            room = data.get('room')
            if room:
                join_room(room)
                emit('room_joined', {'room': room})
                logger.info(f"用户加入房间: {room}")
        except Exception as e:
            logger.error(f"加入房间错误: {str(e)}")
    
    @socketio.on('leave_room')
    def handle_leave_room(data):
        """处理离开房间"""
        try:
            room = data.get('room')
            if room:
                leave_room(room)
                emit('room_left', {'room': room})
                logger.info(f"用户离开房间: {room}")
        except Exception as e:
            logger.error(f"离开房间错误: {str(e)}")
    
    @socketio.on('typing')
    def handle_typing(data):
        """处理正在输入状态"""
        try:
            receiver_id = data.get('receiver_id')
            if receiver_id:
                emit('user_typing', {
                    'user_id': request.sid,
                    'username': 'User'  # 实际应该从token获取用户名
                }, room=str(receiver_id))
        except Exception as e:
            logger.error(f"输入状态错误: {str(e)}")

# 初始化处理器
init_socket_handlers()